package com.ht.managermentserver.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.client.OAuth2ClientContext;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.security.oauth2.client.filter.OAuth2ClientAuthenticationProcessingFilter;
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsAccessTokenProvider;
import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
import org.springframework.security.oauth2.provider.token.RemoteTokenServices;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;

/**
 * oauth2 client
 *
 * @author czy
 */
// @EnableOAuth2Client
@Configuration
@Slf4j
public class Oauth2SecurityConfig {

  @Value("${security.oauth2.client.client-id}")
  private String clientId;

  @Value("${security.oauth2.client.client-secret}")
  private String clientSecret;

  @Value("${security.oauth2.client.access-token-uri}")
  private String accessTokenUri;

  @Value("${security.oauth2.client.user-authorization-uri}")
  private String userAuthorizationUri;

  // private String checktoken_uri = "/";

  private OAuth2ProtectedResourceDetails resource() {
    final ClientCredentialsResourceDetails resource = new ClientCredentialsResourceDetails();
    resource.setClientId(clientId);
    resource.setClientSecret(clientSecret);
    resource.setAccessTokenUri(this.accessTokenUri);
    // resource.setUserAuthorizationUri(this.access_token_uri);

    resource.setScope(Arrays.asList("all"));
    // resource.setGrantType("client_credentials");
    return resource;
  }

  @Bean
  public OAuth2RestTemplate oauth2RestTemplate(final OAuth2ClientContext context) {
    final OAuth2RestTemplate template = new OAuth2RestTemplate(resource(), context);

    // AuthorizationCodeAccessTokenProvider authCodeProvider = new
    // AuthorizationCodeAccessTokenProvider();
    final ClientCredentialsAccessTokenProvider clientProvider =
        new ClientCredentialsAccessTokenProvider();

    // AccessTokenProviderChain provider = new
    // AccessTokenProviderChain(Arrays.asList(clientProvider));
    template.setAccessTokenProvider(clientProvider);
    return template;
  }

  /**
   * 注册处理redirect uri的filter
   *
   * @param oauth2RestTemplate
   * @param tokenService
   * @return
   */
  @Bean
  public OAuth2ClientAuthenticationProcessingFilter oauth2ClientAuthenticationProcessingFilter(
      final OAuth2RestTemplate oauth2RestTemplate, final RemoteTokenServices tokenService) {
    final OAuth2ClientAuthenticationProcessingFilter filter =
        new OAuth2ClientAuthenticationProcessingFilter("/oauth/client_redirect**");
    filter.setRestTemplate(oauth2RestTemplate);
    filter.setTokenServices(tokenService);

    // 设置回调成功的页面
    filter.setAuthenticationSuccessHandler(
        new SimpleUrlAuthenticationSuccessHandler() {
          @Override
          public void onAuthenticationSuccess(
              final HttpServletRequest request,
              final HttpServletResponse response,
              final org.springframework.security.core.Authentication authentication)
              throws IOException, ServletException {
            final OAuth2AuthenticationDetails auth2AuthenticationDetails =
                (OAuth2AuthenticationDetails) authentication.getDetails();
            log.info("登录成功");
            final String tokenValue = auth2AuthenticationDetails.getTokenValue();
            log.info("tokenValue:" + tokenValue);
            this.setAlwaysUseDefaultTargetUrl(true);
            final String redirctUrl = request.getParameter("redirect");
            log.info("redirect_url=" + redirctUrl);
            this.setDefaultTargetUrl(
                "/oauth/client_target?token=" + tokenValue + "&redirect=" + redirctUrl);
            super.onAuthenticationSuccess(request, response, authentication);
          }
        });
    return filter;
  }

  /**
   * 注册check token服务
   *
   * @param details
   * @return
   */
  @Bean
  public RemoteTokenServices tokenService(final OAuth2ProtectedResourceDetails details) {
    final RemoteTokenServices tokenService = new RemoteTokenServices();
    tokenService.setCheckTokenEndpointUrl("http://localhost:8888/server/oauth/check_token");
    tokenService.setClientId(details.getClientId());
    tokenService.setClientSecret(details.getClientSecret());
    return tokenService;
  }
}
